﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using HynuIOTA.Common.Attribute;
using HynuIOTA.Helpers;
using LitJson;

namespace HynuIOTA.Web.Areas.Media.Controllers
{
    public class FileController : BaseController
    {
        [SkipLogin]
        public ActionResult FileManager(string dir = "image",string order = "name", string path = "")
        {
            //String aspxUrl = Request.Path.Substring(0, Request.Path.LastIndexOf("/") + 1);
            //根目录路径，相对路径
            String rootPath = "~/UploadFile/";
            //根目录URL，可以指定绝对路径，比如 http://www.yoursite.com/attached/
            String rootUrl = "~/UploadFile/";
            //图片扩展名
            String fileTypes = "gif,jpg,jpeg,png,bmp";

            String currentPath = "";
            String currentUrl = "";
            String currentDirPath = "";
            String moveupDirPath = "";

            String dirPath = Server.MapPath(rootPath);
            if (String.IsNullOrEmpty(dir) == false)
            {
                if (Array.IndexOf("image,flash,media,file".Split(','), dir) == -1)
                {
                    Response.Write("Invalid Directory name.");
                    Response.End();
                }
                dirPath += dir + "\\";
                rootUrl += dir + "/";
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }
            }

            //根据path参数，设置各路径和URL
            if (path == "")
            {
                currentPath = dirPath;
                currentUrl = rootUrl;
                currentDirPath = "";
                moveupDirPath = "";
            }
            else
            {
                currentPath = dirPath + path;
                currentUrl = rootUrl + path;
                currentDirPath = path;
                moveupDirPath = Regex.Replace(currentDirPath, @"(.*?)[^\/]+\/$", "$1");
            }

            //排序形式，name or size or type
            //不允许使用..移动到上一级目录
            if (Regex.IsMatch(path, @"\.\."))
            {
                return Content("Access is not allowed.");
            }
            //最后一个字符不是/
            if (path != "" && !path.EndsWith("/"))
            {
                return Content("Parameter is not valid.");
            }
            //目录不存在或不是目录
            if (!Directory.Exists(currentPath))
            {
                return Content("Directory does not exist.");
            }

            try
            {
                //遍历目录取得文件信息
                string[] dirList = Directory.GetDirectories(currentPath);
                string[] fileList = Directory.GetFiles(currentPath);

                switch (order)
                {
                    case "size":
                        Array.Sort(dirList, new FileManager.NameSorter());
                        Array.Sort(fileList, new FileManager.SizeSorter());
                        break;
                    case "type":
                        Array.Sort(dirList, new FileManager.NameSorter());
                        Array.Sort(fileList, new FileManager.TypeSorter());
                        break;
                    case "name":
                    default:
                        Array.Sort(dirList, new FileManager.NameSorter());
                        Array.Sort(fileList, new FileManager.NameSorter());
                        break;
                }

                Hashtable result = new Hashtable();
                result["moveup_dir_path"] = moveupDirPath;
                result["current_dir_path"] = currentDirPath;
                result["current_url"] = Url.Content(currentUrl);
                result["total_count"] = dirList.Length + fileList.Length;
                List<Hashtable> dirFileList = new List<Hashtable>();
                result["file_list"] = dirFileList;
                foreach (var item in dirList)
                {
                    var dirInfo = new DirectoryInfo(item);
                    Hashtable hash = new Hashtable();
                    hash["is_dir"] = true;
                    hash["has_file"] = (dirInfo.GetFileSystemInfos().Length > 0);
                    hash["filesize"] = 0;
                    hash["is_photo"] = false;
                    hash["filetype"] = "";
                    hash["filename"] = dirInfo.Name;
                    hash["datetime"] = dirInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                    dirFileList.Add(hash);
                }
                foreach (var t in fileList)
                {
                    FileInfo file = new FileInfo(t);
                    Hashtable hash = new Hashtable();
                    hash["is_dir"] = false;
                    hash["has_file"] = false;
                    hash["filesize"] = file.Length;
                    hash["is_photo"] = (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) >= 0);
                    hash["filetype"] = file.Extension.Substring(1);
                    hash["filename"] = file.Name;
                    hash["datetime"] = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                    dirFileList.Add(hash);
                }
                return OpContext.Json(result);
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }

        }

        [SkipLogin]
        public async Task<ActionResult> UploadFile(string dir = "image")
        {
            string savePath = Url.Content("~/UploadFile/");
            string saveUrl = savePath;

            //定义允许上传的文件扩展名
            Hashtable extTable = new Hashtable();
            extTable.Add("image", "gif,jpg,jpeg,png,bmp");
            extTable.Add("flash", "swf,flv");
            extTable.Add("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
            extTable.Add("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
            int maxSize = 1000000;

            HttpPostedFileBase file = Request.Files["imgFile"];
            if (file == null || string.IsNullOrEmpty(file.FileName))
            {
                return UploadFileError("请选择文件！");
            }

            string dirPath = Server.MapPath(savePath);
            if (!Directory.Exists(dirPath))
            {
                return UploadFileError("上传目录不存在!");
            }

            if (file.InputStream == null || file.InputStream.Length > maxSize)
            {
                return UploadFileError("上传文件大小超过限制");
            }

            if (extTable.Contains(dir) == false)
            {
                return UploadFileError("目录名称不正确！");
            }

            string fileExt = Path.GetExtension(file.FileName)?.ToLower();
            string[] allowExt = ((String)extTable[dir]).Split(',');
            if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(allowExt, fileExt.Substring(1).ToLower()) == -1)
            {
                return UploadFileError("上传文件扩展名是不允许的扩展名。\n只允许" + ((String)extTable[dir]) + "格式。");
            }

            //创建文件夹
            dirPath = Path.Combine(dirPath, dir);
            saveUrl = Path.Combine(saveUrl, dir);
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            String ymd = DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);
            dirPath = Path.Combine(dirPath, ymd);
            saveUrl = Path.Combine(saveUrl, ymd);


            try
            {
                if (Directory.Exists(dirPath) == false)
                {
                    Directory.CreateDirectory(dirPath);
                }
            }
            catch (Exception ex)
            {
                return UploadFileError(ex.Message);
            }

            string newFileName = Path.ChangeExtension(Guid.NewGuid().ToString(), fileExt);
            string filePath = Path.Combine(dirPath, newFileName);
            using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
            {
                try
                {

                    await file.InputStream.CopyToAsync(fs);
                    await fs.FlushAsync();

                }
                catch (Exception ex)
                {
                    return UploadFileError(ex.Message);
                }
            }
            return OpContext.Json(new { error = 0, url = Url.Content(Path.Combine(saveUrl, newFileName).Replace('\\', '/')) }, "text/html; charset=UTF-8");
        }

        private ContentResult UploadFileError(string msg)
        {
            return OpContext.Json(new { error = 1, message = msg }, "text/html; charset=UTF-8");
        }
    }
}